From 37cd9696df91c649423e181f6dfe16c2baf1e97c Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Sun, 3 Jun 2007 10:15:50 -0400 Subject: [PATCH] [POWERPC][XEN] Simplify Dom0 Loading. - Load the kernel image before all other images, this allows for debugging image location to be way easier. - Simplify libelf usage Signed-off-by: Jimi Xenidis --- xen/arch/powerpc/domain_build.c | 128 +++++++++++++++++--------------- 1 file changed, 69 insertions(+), 59 deletions(-) diff --git a/xen/arch/powerpc/domain_build.c b/xen/arch/powerpc/domain_build.c index d9ff09617c..94cdb7159a 100644 --- a/xen/arch/powerpc/domain_build.c +++ b/xen/arch/powerpc/domain_build.c @@ -68,6 +68,7 @@ int construct_dom0(struct domain *d, struct vcpu *v; ulong dst; u64 *ofh_tree; + ulong firmware_base; uint rma_nrpages = 1 << cpu_default_rma_order_pages(); ulong rma_sz; ulong rma; @@ -78,6 +79,7 @@ int construct_dom0(struct domain *d, ulong mod_len = 0; ulong shared_info_addr; uint extent_size = 1 << cpu_extent_order(); + ulong sz; /* Sanity! */ BUG_ON(d->domain_id != 0); @@ -87,26 +89,6 @@ int construct_dom0(struct domain *d, printk("*** LOADING DOMAIN 0 ***\n"); - rc = elf_init(&elf, (void *)image_start, image_len); - if (rc) - return rc; -#ifdef VERBOSE - elf_set_verbose(&elf); -#endif - elf_parse_binary(&elf); - if (0 != (elf_xen_parse(&elf, &parms))) - return rc; - - printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n", - elf_64bit(&elf) ? "64-bit" : "32-bit", - elf.pstart, elf.pend); - - /* elf contains virtual addresses that can have the upper bits - * masked while running in real mode, so we do the masking as well - * as well */ - parms.virt_kend = RM_MASK(parms.virt_kend, 42); - parms.virt_entry = RM_MASK(parms.virt_entry, 42); - /* default is the max(1/16th of memory, CONFIG_MIN_DOM0_PAGES) */ if (dom0_nrpages == 0) { dom0_nrpages = total_pages >> 4; @@ -196,41 +178,43 @@ int construct_dom0(struct domain *d, v = d->vcpu[0]; cpu_init_vcpu(v); - /* OF usually sits here: - * - Linux needs it to be loaded before the vmlinux or initrd - * - AIX demands it to be @ 32M. - */ - dst = (32 << 20); - - /* Put stack below everything. */ - v->arch.ctxt.gprs[1] = dst - STACK_FRAME_OVERHEAD; - - /* copy relative to Xen */ - dst += rma; + /* convert xen pointer shared_info into guest physical */ + shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page); - ASSERT((dst - rma) + (ulong)firmware_image_size < eomem); - printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma); - memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size); + /* start loading stuff */ + rc = elf_init(&elf, (void *)image_start, image_len); + if (rc) + return rc; +#ifdef VERBOSE + elf_set_verbose(&elf); +#endif + elf_parse_binary(&elf); + if (0 != (elf_xen_parse(&elf, &parms))) + return rc; - v->arch.ctxt.gprs[5] = (dst - rma); - ofh_tree = (u64 *)(dst + 0x10); - ASSERT(*ofh_tree == 0xdeadbeef00000000); + printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n", + elf_64bit(&elf) ? "64-bit" : "32-bit", + elf.pstart, elf.pend); - /* accomodate for a modest bss section */ - dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE); - ASSERT((dst - rma) + oftree_len < eomem); + /* elf contains virtual addresses that can have the upper bits + * masked while running in real mode, so we do the masking as well + * as well */ + parms.virt_kend = RM_MASK(parms.virt_kend, 42); + parms.virt_entry = RM_MASK(parms.virt_entry, 42); - *ofh_tree = dst - rma; - printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma, - oftree_len); - memcpy((void *)dst, (void *)oftree, oftree_len); - dst = ALIGN_UP(dst + oftree_len, PAGE_SIZE); + /* set the MSR bit correctly */ + if (elf_64bit(&elf)) + v->arch.ctxt.msr = MSR_SF; + else + v->arch.ctxt.msr = 0; /* Load the dom0 kernel. */ - elf.dest = (void *)dst; + elf.dest = (void *)(parms.virt_kstart + rma); + elf_load_binary(&elf); - v->arch.ctxt.pc = dst - rma + (parms.virt_entry - parms.virt_kstart); - dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE); + v->arch.ctxt.pc = parms.virt_entry; + + dst = ALIGN_UP(parms.virt_kend + rma, PAGE_SIZE); /* Load the initrd. */ if (initrd_len > 0) { @@ -247,15 +231,46 @@ int construct_dom0(struct domain *d, printk("no initrd\n"); } - if (elf_64bit(&elf)) { - v->arch.ctxt.msr = MSR_SF; - } else { - v->arch.ctxt.msr = 0; - } - v->arch.ctxt.gprs[2] = 0; v->arch.ctxt.gprs[3] = mod_start; v->arch.ctxt.gprs[4] = mod_len; + /* OF usually sits here: + * - Linux needs it to be loaded before the vmlinux or initrd + * - AIX demands it to be @ 32M. + */ + firmware_base = (32 << 20); + if (dst - rma > firmware_base) + panic("Firmware [0x%lx] will over-write images ending: 0x%lx\n", + firmware_base, dst - rma); + dst = firmware_base + rma; + + /* Put stack below firmware. */ + v->arch.ctxt.gprs[1] = dst - rma - STACK_FRAME_OVERHEAD; + v->arch.ctxt.gprs[2] = 0; + + ASSERT((dst - rma) + (ulong)firmware_image_size < eomem); + printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma); + memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size); + + v->arch.ctxt.gprs[5] = (dst - rma); + ofh_tree = (u64 *)(dst + 0x10); + ASSERT(*ofh_tree == 0xdeadbeef00000000); + + /* accomodate for a modest bss section */ + dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE); + + ASSERT((dst - rma) + oftree_len < eomem); + + *ofh_tree = dst - rma; + printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma, + oftree_len); + memcpy((void *)dst, (void *)oftree, oftree_len); + + /* fixup and add stuff for dom0 */ + sz = ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr); + printk("modified OFD size: 0x%lx\n", sz); + dst = ALIGN_UP(dst + sz + PAGE_SIZE, PAGE_SIZE); + printk("dom0 initial register state:\n" " pc %016lx msr %016lx\n" " r1 %016lx r2 %016lx r3 %016lx\n" @@ -268,11 +283,6 @@ int construct_dom0(struct domain *d, v->arch.ctxt.gprs[4], v->arch.ctxt.gprs[5]); - /* convert xen pointer shared_info into guest physical */ - shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page); - - ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr); - v->is_initialised = 1; clear_bit(_VPF_down, &v->pause_flags); -- 2.30.2